home *** CD-ROM | disk | FTP | other *** search
/ World of Video / World of Video.iso / gfxprograms / viewers / edushow / edushow.c < prev    next >
C/C++ Source or Header  |  1995-02-13  |  16KB  |  624 lines

  1. /*********************************************************************
  2.  * EDUSHOW    Copyright 1990 Laurence Vanhelsuwé
  3.  * -------
  4.  * Specialised interactive slideshow program for educational purposes 
  5.  * or giving presentations to groups of people.
  6.  *
  7.  * Written by L.Vanhelsuwé    © 1990
  8.  *
  9.  * - started/finished on 12-Mar-1990
  10.  * - quick check before releasing to Fish PD 22-May-1994
  11.  *********************************************************************/
  12.  
  13.  
  14. #include    <exec/types.h>
  15. #include    <intuition/intuition.h>
  16.  
  17. #include    <clib/exec_protos.h>            // ANSI function prototypes
  18. #include    <clib/alib_protos.h>
  19. #include    <clib/dos_protos.h>
  20. #include    <clib/graphics_protos.h>
  21. #include    <clib/intuition_protos.h>
  22.  
  23. #define        FIRST_ARG        argv[1] 
  24. #define        LF                (0x0a)
  25. #define        MAX_COLOR        16    /** IN HIRES SCREEN            **/
  26. #define        COLOR            15    /** MASK FOR HARDWARE COLOR PRIMARY    **/
  27. #define        CHUNK_ID        long
  28. #define        CHUNK_LEN        long
  29.  
  30. #define        COLORS            16
  31.  
  32. #define        NEXT_COLOR        ' '
  33. #define        PREV_COLOR        '\b'
  34. #define        NEXT_PICTURE    'n'
  35. #define        PREV_PICTURE    'p'
  36. #define        QUIT            'q'
  37.  
  38. #define        IN                1        /** COLOR FADE DIRECTIONS **/
  39. #define        OUT                0
  40.  
  41. #define        MAX_ALLOCS    40            // maximum objects allocated 
  42.  
  43. /************************************************************************/
  44.  
  45. char ver[] = "$VER: EDUSHOW v0.9 (12-MAR-90) by Laurence Vanhelsuwé";
  46.  
  47. char screentitle[] = 
  48. "WICPUG 68000 Assembly Language Course -Educational Slideshow 0.9 (C) LVA 1990";
  49.  
  50. int count_lines(char *text);        /** AND ZERO TERMINATE LINES !! **/
  51. int cache_all_pictures(char * list_of_pictures, int number_of_pics);
  52.  
  53.         /****** non "int" functions ******/
  54.         
  55. char  * load_file(char *name);        /** CACHES ANY FILE IN MEMORY    **/
  56. char  * next_string(char*n);        /** NEXT START OF LINE        **/
  57. char  * expand_line(char*a,char*b);    /** UN-COMPRESS RUN-LENGTH LINE **/
  58. char  * find_chunk(char*s,char*n);    /** FIND START OF ANY iff CHUNK **/
  59. char    get_input(void);            /** USER INPUT ROUTINE        **/
  60.  
  61. short    scale_color(short,short);    /** FADE COLOR n BY FACTOR x    **/
  62.  
  63. void    fade_color(int p, int d);    /** FADES PEN n IN or OUT    **/
  64. void    fade_screen(int dir);
  65. void    decode_color_maps(struct mem_iff_pic *mip_array,int n);    /** UNPACKS iff CMAP INTO INTERNAL FORM **/
  66. void    decompress_pic(void);        /** PUT COMPRESSED PICTURE ON SCREEN **/
  67. void    open_screen(void);            /** OPEN AN Intuition SCREEN    **/
  68. void    lights_out(void);            /** ALL PENS ARE SET TO BLACK    **/
  69. void    close_everything(void);        /** DEALLOCATE,FREE,CLOSE ALL    **/
  70. void    next_color(void);            /** FADE IN NEXT COLOR IN SLIDE **/
  71. void    prev_color(void);            /** FADE OUT CURRENT COLOR IN SLIDE **/
  72. void    next_picture(void);                /** FADE OUT THIS SLIDE, SHOW NEXT **/
  73. void    prev_picture(void);            /** FADE OUT THIS SLIDE, SHOW PREV **/
  74.  
  75. struct Screen * OpenScreen();
  76. struct Window * OpenWindow();
  77.  
  78.         /****** global variables ******/
  79. struct IntuitionBase *IntuitionBase;
  80. struct GfxBase        *GfxBase;
  81.  
  82. struct Screen *screen;
  83. struct Window *window;
  84. struct ViewPort *vport;
  85.  
  86. int current_pic,current_color,lessons;
  87.  
  88. int alloc_num=0;
  89.  
  90.         /****** global structures *****/
  91. struct iff_header {            /** THIS DEFINES THE iff HEADER **/
  92.     CHUNK_ID    form_id;
  93.     CHUNK_LEN    form_len;
  94.     CHUNK_ID    form_type;
  95.     CHUNK_ID    bmhdr_id;
  96.     CHUNK_LEN    bmhdr_len;
  97.     short        width;
  98.     short        height;
  99.     long        unknown;
  100.     BYTE        planes;
  101.     BYTE        pad0;
  102.     BYTE        compression;
  103.     BYTE        pad1;
  104.     long        pad2,pad3;
  105.     CHUNK_ID    cmap_id;
  106.     CHUNK_LEN    cmap_len;
  107.     char        cmap[16*3];
  108.     CHUNK_ID    body_id;
  109.     CHUNK_LEN    body_len;
  110.     char        body;
  111. };    
  112.  
  113. struct mem_iff_pic {
  114.     struct iff_header *file_buffer;    /** PTR TO COMPRESSED IFF PIC **/
  115.     char    *body_ptr;        /** PTR TO BODY CHUNK IFF **/
  116.     short cmap [COLORS][3];        /** EXPANDED COLOR PALETTE */
  117. };
  118.  
  119. struct mem_iff_pic *lesson_pics;
  120.  
  121. struct mem_block {            /** define a struct for every object **/
  122.     char    *ptr;            /** that we've allocated             **/
  123.     int        size;
  124. } allocations[MAX_ALLOCS];
  125.  
  126. /*************************************************************************/
  127. /*************************** START OF MAIN *******************************/
  128. /*************************************************************************/
  129.  
  130. main(argc,argv)            /** TAKES A SCRIPT FILE AS ARGUMENT **/
  131. int argc;
  132. char *argv[];
  133. {
  134.     char *script_buffer;
  135.     char user_input;
  136.     int    script_size;
  137.     int    success;
  138.     
  139.     script_size = 0;
  140.     
  141. //    printf("Filename = %s # of args = %d\n",FIRST_ARG,argc);
  142.     if (argc != 2) exit (100);
  143.  
  144.     printf("EDUcational slideSHOW V0.9                   (C) 1990 L. Vanhelsuwé\n");
  145.     printf("--------------------------                   -------------------------\n");
  146.     printf("\n");
  147.     printf("Use the following keys to control the presentation:\n");
  148.     printf("\n");
  149.     printf("SPACE...... fade in next image element\n");
  150.     printf("BACKSPACE.. fade out current image element\n");
  151.     printf("'N'........ fade in next slide\n");
  152.     printf("'P'........ fade in previous slide\n\n");
  153.     printf("'Q'........ to quit\n\n");
  154.  
  155.     printf("HIT <ENTER> to start presentation."); getch();
  156.     printf("\n");
  157.     
  158.     GfxBase          = (struct GfxBase *) OpenLibrary("graphics.library",0);
  159.     IntuitionBase = (struct IntuitionBase*) OpenLibrary("intuition.library",0);
  160.     
  161.     script_buffer = load_file(FIRST_ARG);        /** LOAD SCRIPT **/
  162.         if (script_buffer == NULL) exit(100);
  163.  
  164.     lessons = count_lines(script_buffer);        /** HOWMANY PICS **/
  165.     printf("Number of Slides in this presentation = %d \n",lessons);
  166.  
  167.     lesson_pics = (struct mem_iff_pic*)
  168.          AllocMem(lessons*sizeof (struct mem_iff_pic),0); 
  169.  
  170.                             /** LOAD ALL PICS **/
  171.     success = cache_all_pictures(script_buffer,lessons);
  172.     if (success == FALSE)
  173.     {
  174.         printf("Cache technique failed this time....\n");
  175.         exit(100);
  176.     }
  177.  
  178.     decode_color_maps(lesson_pics,lessons);
  179.  
  180.     open_screen();            /** OPEN SLIDESHOW SCREEN    **/
  181.     current_pic = -1;        /** START SHOW OFF ....        **/
  182.     next_picture();            
  183.     
  184.     while ( (user_input = get_input()) != QUIT)
  185.     {
  186.         switch (user_input)
  187.         {
  188.             case 13:
  189.             case NEXT_COLOR:    next_color(); break;
  190.             case PREV_COLOR:    prev_color(); break;
  191.             case NEXT_PICTURE:    next_picture(); break;
  192.             case PREV_PICTURE:    prev_picture(); break;
  193.  
  194.             default:
  195.                 printf("Don't know event %d !\n",(int) user_input);
  196.         }
  197.     }
  198.  
  199.     close_everything();        /** RELEASE SCREEN,CACHE ETC..**/
  200.  
  201.     CloseLibrary((struct Library*)GfxBase);
  202.     CloseLibrary((struct Library*)IntuitionBase);
  203.  
  204.     printf ("\n\nHave a nice day..\n");
  205. }
  206.     
  207. /***********************************************************************/
  208. // Turn screen dark, decompress next slide, fade it in.
  209. /***********************************************************************/
  210. void next_picture()
  211. {
  212.     if (current_pic != (lessons -1) )
  213.     {
  214.         lights_out();
  215.         current_pic++;
  216.         decompress_pic();
  217.         
  218.         current_color = 1; fade_color(current_color,IN);
  219.     }
  220. }
  221. /***********************************************************************/
  222. // Fade next "subject" in (mapped to a unique pen color)
  223. // Goto next slide if no more subjects.
  224. /***********************************************************************/
  225. void next_color()
  226. {
  227.     current_color++;
  228.     if (current_color < MAX_COLOR)
  229.     {
  230.         fade_color(current_color,IN);
  231.     }
  232.     else
  233.     {
  234.         next_picture();
  235.     }
  236. }    
  237. /***********************************************************************/
  238. // Do opposite of next_color()
  239. /***********************************************************************/
  240. void prev_color()
  241. {
  242.     if (current_color != 1)
  243.     {
  244.         fade_color( current_color, OUT );
  245.         current_color--;
  246.     }
  247.     else
  248.     {
  249.         prev_picture();
  250.     }
  251. }
  252. /***********************************************************************/
  253. // Backtrack by going back to previous slide
  254. /***********************************************************************/
  255. void prev_picture()
  256. {
  257.     if (current_pic != 0)
  258.     {
  259.         lights_out();
  260.         current_pic--;
  261.         decompress_pic();
  262.         fade_screen(IN);
  263.         current_color = 1;
  264.     }
  265. }
  266. /***********************************************************************/
  267. char get_input()        /** WAIT FOR ANY ASCII KEY PRESS **/
  268. {
  269.     int type = -1;
  270.     char key;
  271.     struct IntuiMessage * msg;
  272.  
  273.     while (type != VANILLAKEY)
  274.     {
  275.         Wait(1 << window->UserPort->mp_SigBit);
  276.  
  277.         while (msg = (struct IntuiMessage *) GetMsg(window->UserPort))
  278.         {
  279.             type = msg->Class;
  280.             key = (char) msg->Code;
  281.             ReplyMsg((struct Message*)msg);
  282.         }
  283.     }
  284.  
  285.     return key;
  286. }
  287. /***********************************************************************/
  288. // Cache a picture file in its entirety.
  289. /***********************************************************************/
  290.  
  291. char * load_file(name)
  292. char * name;
  293. {
  294.     int file_handle;
  295.     int file_size;
  296.     
  297.     char * buff_ptr;
  298.     
  299.  
  300.     file_handle = Open(name,MODE_OLDFILE);
  301.     if (file_handle) {
  302.         Seek(file_handle,0L,OFFSET_END);
  303.         file_size = Seek(file_handle,0L,OFFSET_BEGINNING);
  304.         
  305.         buff_ptr = (char *) AllocMem(file_size +1,0); /* ANY MEM */
  306.         if (buff_ptr == NULL) 
  307.             return NULL;        /* ALLOC FAILED */
  308.         
  309.         allocations[alloc_num].ptr  = buff_ptr;            // Track allocations
  310.         allocations[alloc_num].size = file_size+1;
  311.         alloc_num++;
  312.  
  313.         Read(file_handle,buff_ptr,file_size);
  314.         Close(file_handle);
  315.         
  316.         *(buff_ptr+file_size) = '\0';    /** ADD END TAG **/
  317.         return buff_ptr;
  318.     } else {
  319.         printf("OPEN FAILED : file %s \n",name);
  320.         exit(100);
  321.     }
  322. }
  323.  
  324. /***********************************************************************/
  325. // Go through script counting # of lines (== number of slides)
  326. /***********************************************************************/
  327. int count_lines(text)        /** AND ZERO TERMINATE LINES !! **/
  328. char * text;
  329. {
  330.     int lines=0;
  331.     register char *text_ptr=text;
  332.     register char ch;
  333.     
  334.     while (ch = *text_ptr++)    /** UNTIL WE HIT END OF TEXT **/
  335.     {
  336.         if (ch == LF)         /** COUNT LINE FEEDS **/
  337.         {
  338.             lines++;
  339.             *(text_ptr-1) = '\0';    /* CHANGE INTO C-STRING **/
  340.         }
  341.     }
  342.     
  343.     return lines;
  344. }
  345.  
  346. /***********************************************************************/
  347. int cache_all_pictures(list_of_pictures,number_of_pics)
  348. char * list_of_pictures;
  349. int number_of_pics;
  350. {
  351.     int i;
  352.     struct mem_iff_pic *mip;
  353.     char *ptr, *fname = list_of_pictures;
  354.     
  355.     mip = lesson_pics;
  356.     
  357.     for (i=0; i<number_of_pics; i++,mip++) {
  358.  
  359. //        printf("FNAME #%d -> %s \n",i,fname);
  360.  
  361.         mip->file_buffer = (struct iff_header *) load_file(fname);
  362.  
  363. //        printf("Mmmmm... cached at %x \n", (int) mip->file_buffer);
  364.  
  365.         if (mip->file_buffer == NULL) {
  366.             printf("Madonna !*&#$% NO MORE MEMORY !\n");
  367.             return FALSE;
  368.         }
  369.     
  370.         ptr = (char *) &mip->file_buffer->bmhdr_id;
  371.         
  372.         mip->body_ptr = find_chunk(ptr,"BODY");
  373.         
  374.         fname = next_string(fname);
  375.     }
  376.     return TRUE;
  377. }
  378. /***********************************************************************/
  379. char * next_string(text)
  380. char * text;
  381. {
  382.     register char *ptr=text;
  383.     
  384.     while (*ptr++)
  385.         ; 
  386.     
  387.     return ptr;
  388. }
  389. /***********************************************************************/
  390. char * find_chunk(start,name)
  391. char *start,*name;
  392. {
  393.     long *len;
  394.     
  395.     while (    (start[0] != name[0]) || (start[1] != name[1]) ||
  396.         (start[2] != name[2]) || (start[3] != name[3])    )
  397.     {
  398.         len = (long *) start +1;
  399.         start += (*len)+8;
  400.     }
  401.     
  402.     return start+8;
  403. }
  404. /***********************************************************************/
  405. void decode_color_maps(mip_array,entries)
  406. struct mem_iff_pic *mip_array;
  407. int entries;
  408. {
  409.     int c,i;
  410.     struct mem_iff_pic *mip=mip_array;
  411.     struct iff_header  *ptr;
  412.     char   *gun_ptr;
  413.     
  414.     for(i=0; i<entries; i++) {
  415.         ptr = (struct iff_header*) mip->file_buffer;
  416.  
  417. //        printf("Planes = %d ",(int) ptr->planes);
  418. //        printf("Width = %d Height = %d ",
  419. //            (int) ptr->width, (int) ptr->height);
  420. //        printf("Compressed = %s",ptr->compression?"YES":"NO");
  421. //        printf("\n");
  422.                 
  423.         gun_ptr = &ptr->cmap[0];
  424.         for(c=0; c<16; c++)
  425.         {
  426.             mip->cmap[c][0] = (short) (*(gun_ptr++)>>4) &COLOR;
  427.             mip->cmap[c][1] = (short) (*(gun_ptr++)>>4) &COLOR;
  428.             mip->cmap[c][2] = (short) (*(gun_ptr++)>>4) &COLOR;
  429.         }
  430.  
  431.         mip++;
  432.     }
  433. }
  434. /***********************************************************************/
  435. void lights_out()
  436. {
  437.     int color;
  438.     
  439.     for (color=0; color<16; color++)
  440.     {
  441.         SetRGB4(vport,color,0,0,0);
  442.     }
  443. }
  444. /***********************************************************************/
  445. // Fade a CLUT from dark to normal or vice versa.
  446. /***********************************************************************/
  447. void fade_screen(direction)
  448. int direction;
  449. {
  450.     short i,pen,min,max,incr;
  451.     short red,green,blue;
  452.  
  453.     struct mem_iff_pic *mip;
  454.     
  455.     mip = lesson_pics + current_pic;
  456.     
  457.     if (direction == IN) {
  458.         min = 0; max = MAX_COLOR; incr = 1;
  459.     } else {
  460.         min = MAX_COLOR; max = 0; incr = -1;
  461.     }
  462.  
  463.     for (i=min; i != max ; i = i+incr)    /** INTENSITY 0..16 **/
  464.     {
  465.         for (pen=0; pen < MAX_COLOR; pen++)    /** PEN 0..15 **/
  466.         {
  467.             red   = scale_color(mip->cmap[pen][0],i);
  468.             green = scale_color(mip->cmap[pen][1],i);
  469.             blue  = scale_color(mip->cmap[pen][2],i);
  470.             SetRGB4(vport,pen,red,green,blue);
  471.         }
  472.  
  473.         Delay(1);
  474.     }
  475. }
  476. /***********************************************************************/
  477. // Core routine for fade:  "scale" an RGB triplet by a brightness factor.
  478. /***********************************************************************/
  479. void fade_color(pen,direction)
  480. int pen,direction;
  481. {
  482.     short i,min,max,incr;
  483.     short red,green,blue;
  484.     struct mem_iff_pic *mip;
  485.     
  486.     mip = lesson_pics + current_pic;
  487.     
  488.     if (direction == IN) {
  489.         min = 0; max = MAX_COLOR; incr = 1;
  490.     } else {
  491.         min = MAX_COLOR; max = 0; incr = -1;
  492.     }
  493.  
  494.     for (i=min; i != max ; i = i+incr) {
  495.         red   = scale_color(mip->cmap[pen][0],i);
  496.         green = scale_color(mip->cmap[pen][1],i);
  497.         blue  = scale_color(mip->cmap[pen][2],i);
  498.         
  499.         SetRGB4(vport,pen,red,green,blue);
  500.         Delay(1);
  501.     }
  502. }
  503. /***********************************************************************/
  504. short int scale_color(primary,intens)
  505. short primary;
  506. short intens;
  507. {
  508.     primary = (primary*intens)>>4;
  509.     return primary;
  510. }
  511. /***********************************************************************/
  512. // Expand cached IFF picture to currently darkened screen.
  513. /***********************************************************************/
  514. void decompress_pic()
  515. {
  516.     short scan_line;        /** SCREEN LINE COUNTER **/
  517.     char *p1,*p2,*p3,*p4,*data;    /** PTRS TO IFF & PLANES **/
  518.     struct mem_iff_pic *mip;    /** PTR TO PICTURE DESCRIPTOR **/
  519.     
  520.     mip = lesson_pics + current_pic;
  521.     data = mip->body_ptr;
  522.     
  523.     p1 = screen->BitMap.Planes[0];    /** FIND BITPLANES OF SCREEN **/
  524.     p2 = screen->BitMap.Planes[1];
  525.     p3 = screen->BitMap.Planes[2];
  526.     p4 = screen->BitMap.Planes[3];
  527.     
  528.     for(scan_line=0; scan_line<200; scan_line++) {
  529.         data = expand_line(data,p1);    /** DECODE ONE LINE PER */
  530.         data = expand_line(data,p2);    /** PLANE AT A TIME */
  531.         data = expand_line(data,p3);
  532.         data = expand_line(data,p4);
  533.         
  534.         p1 += 80; p2 += 80; p3 += 80; p4 += 80;    /** NEXT LINE.. **/
  535.     }
  536. }
  537. /***********************************************************************/
  538. char * expand_line(data,plane_ptr)    /** RUN-LENGTH DECOMPRESSOR **/
  539. char *data,*plane_ptr;
  540. {
  541.     char code,pattern,*eol;
  542.     
  543.     eol = plane_ptr +80;        /** CALC END OF LINE **/
  544.     
  545.     while (plane_ptr != eol) {
  546.         code = *data++;        /** GET ENCRYPTION TYPE && 'N' **/
  547.         
  548.         if (code < 0)    /** NEGATIVE : REPLICATE NEXT BYTE **/
  549.         {
  550.             code = (-code) +1;
  551.             pattern = *data++;
  552.             while (code--)
  553.             {
  554.                 *plane_ptr++ = pattern;
  555.             }
  556.         } else {        /** POSITIVE : COPY LITERAL RUN **/
  557.             code++;
  558.             while (code--)
  559.             {
  560.                 *plane_ptr++ = *data++;
  561.             }
  562.         }
  563.     }
  564.     
  565.     return data;        /** RETURN UPDATED SOURCE PTR **/
  566. }
  567. /***********************************************************************/
  568. void open_screen() {
  569.  
  570. static struct NewScreen myscreen =    /** INTUITION SCREEN **/
  571. {                    /** PARAMETER BLOCK **/
  572.     0,0,
  573.     640,200,
  574.     4,
  575.     1,0,
  576.     HIRES,
  577.     CUSTOMSCREEN,
  578.     NULL,screentitle,
  579.     NULL,NULL
  580. };
  581.  
  582. struct NewWindow mywindow =        /** INTUITION WINDOW    **/
  583. {                    /** PARAMETER BLOCK    **/
  584.     0,0,
  585.     640,200,
  586.     255,255,
  587.     VANILLAKEY,            /** WANT KEY PRESSES    **/
  588.     BACKDROP+ACTIVATE,
  589.     NULL,NULL,
  590.     NULL,                /* NO TITLE */
  591.     NULL,NULL,
  592.     0,0,640,200,
  593.     CUSTOMSCREEN
  594. };
  595.     
  596.     screen = OpenScreen(&myscreen);            /** MAGIC ! **/
  597.     if (screen == NULL) {
  598.         printf("Damn You : NO SCREEN !\n");
  599.         exit(100);
  600.     }
  601.     
  602.     vport = &screen->ViewPort;    /** HANDLE FOR COLOR CHANGES **/
  603.  
  604.     mywindow.Screen = screen;
  605.     window = OpenWindow(&mywindow);
  606. }
  607. /***********************************************************************/
  608. void close_everything()
  609. {
  610.     int i;
  611.  
  612.     CloseWindow(window);
  613.     CloseScreen(screen);
  614.  
  615.     for (i=0; i< alloc_num; i++) {
  616.         FreeMem(allocations[i].ptr, allocations[i].size);
  617.     }
  618.  
  619.     FreeMem((char*) lesson_pics, lessons * sizeof(struct mem_iff_pic));
  620.     
  621.     /* return cached file buffers & descriptor array */
  622. }
  623. /***********************************************************************/
  624.